iT邦幫忙

2024 iThome 鐵人賽

DAY 10
0

前言

昨天我們利用網頁的資料來進行LLM的資訊擴充,今天我們嘗試不同的資料來源,這次我們試試看CSV檔案

正文

資料來源

我們使用政府的資料開放平台的低收入戶及中低收入戶之戶數及人數統計CSV檔案
https://ithelp.ithome.com.tw/upload/images/20240909/20168697XYECLrIVyN.png
網址:https://data.gov.tw/dataset/160963

程式碼

  • 大部分流程和之前一樣,先引入模型
from langchain_openai import ChatOpenAI, OpenAIEmbeddings
import os
# 1. Create model
os.environ["OPENAI_API_KEY"] = "你的OpenAPI key"

model = ChatOpenAI(model="gpt-4o")

embeddingmodel = OpenAIEmbeddings(model="text-embedding-ada-002")

接著在載入檔案的地方,import CSVLoader

from langchain_community.document_loaders.csv_loader import CSVLoader
# 2. 載入CSV檔案
loader = CSVLoader(file_path="歷年低收入戶中低收入戶戶數人數統計.csv", encoding="utf-8")
docs = loader.load()

同樣切成數個chunk

from langchain_text_splitters import RecursiveCharacterTextSplitter
# 3. 切分成數個chunk
all_text = "".join(doc.page_content for doc in docs)
print("文件長度: ", end="")
print(len(all_text))
print("chunk長度: ", end="")
chunk_size = 400
print(chunk_size)
text_splitter = RecursiveCharacterTextSplitter(
    chunk_size=chunk_size, chunk_overlap=50)
splits = text_splitter.split_documents(docs)

存入本地向量資料庫

from langchain_chroma import Chroma
# 4. 轉換成embedding,儲存進Chroma向量資料庫.
vectorstore = Chroma.from_documents(
    documents=splits, embedding=embeddingmodel)
retriever = vectorstore.as_retriever()

接著製作Chain

from langchain_core.prompts import PromptTemplate
from langchain_core.output_parsers import StrOutputParser
# 5. 做成chain.
template = """使用以下的上下文來回答最後的問題。
如果你不知道答案,就直接說你不知道,不要編造答案。
最多用三句話,並保持回答簡明扼要。

{context}

使用者提供的額外資訊:
{user_input}
"""

custom_rag_prompt = PromptTemplate.from_template(template)


def format_docs(docs):
    return "\n\n".join(doc.page_content for doc in docs)


rag_chain = (
    {"context": retriever | format_docs, "user_input": lambda x: x}
    | custom_rag_prompt
    | model
    | StrOutputParser()
)
  • 小提醒,rag_chain.invoke之後,會送至lambda函數的x變數,但lambda x: x則表示保持原樣,傳入到prompt之中

最後呼叫

# 6. 呼叫
result = rag_chain.invoke(
    "低收入戶人數上從過去的年份到最新的幾個年份有什麼樣的變化嗎?")
print(result)

完整程式碼

from langchain_openai import ChatOpenAI, OpenAIEmbeddings
import os
from langchain_community.document_loaders.csv_loader import CSVLoader
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_chroma import Chroma
from langchain_core.prompts import PromptTemplate
from langchain_core.output_parsers import StrOutputParser

# 1. Create model
os.environ["OPENAI_API_KEY"] = "你的OpenAPI key"

model = ChatOpenAI(model="gpt-4o")

embeddingmodel = OpenAIEmbeddings(model="text-embedding-ada-002")


# 2. 載入CSV檔案
loader = CSVLoader(file_path="歷年低收入戶中低收入戶戶數人數統計.csv", encoding="utf-8")
docs = loader.load()

# 3. 切分成數個chunk
all_text = "".join(doc.page_content for doc in docs)
print("文件長度: ", end="")
print(len(all_text))
print("chunk長度: ", end="")
chunk_size = 400
print(chunk_size)
text_splitter = RecursiveCharacterTextSplitter(
    chunk_size=chunk_size, chunk_overlap=50)
splits = text_splitter.split_documents(docs)


# 4. 轉換成embedding,儲存進Chroma向量資料庫.
vectorstore = Chroma.from_documents(
    documents=splits, embedding=embeddingmodel)
retriever = vectorstore.as_retriever()


# 5. 做成chain.
template = """使用以下的上下文來回答最後的問題。
如果你不知道答案,就直接說你不知道,不要編造答案。
最多用三句話,並保持回答簡明扼要。

{context}

使用者提供的額外資訊:
{user_input}
"""

custom_rag_prompt = PromptTemplate.from_template(template)


def format_docs(docs):
    return "\n\n".join(doc.page_content for doc in docs)


rag_chain = (
    {"context": retriever | format_docs, "user_input": lambda x: x}
    | custom_rag_prompt
    | model
    | StrOutputParser()
)

# 6. 呼叫
result = rag_chain.invoke(
    "低收入戶人數上從過去的年份到最新的幾個年份有什麼樣的變化嗎?")
print(result)

執行結果

文件長度: 2875
chunk長度: 400
低收入戶人數從2005年的211292人增加到2009年的256342人,再增加到2011年的314282人,最後在2013年達到361765人。總體來看,低收入戶人數逐年增加。

上一篇
day9 打造智能新聞分析系統:從資料抓取到GenAI智慧回應
下一篇
day11 文字程式檔的智慧學習:讓LLM成為你的程式碼教學助手
系列文
智能雲端架構圖生成:結合LangChain&LangGrpah與Rag的創新應用27
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言